package com.rxw.nutmall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.rxw.nutmall.page.PageData;
import com.rxw.nutmall.product.entity.Category;
import com.rxw.nutmall.product.mapper.CategoryMapper;
import com.rxw.nutmall.product.service.CategoryService;
import com.rxw.nutmall.service.impl.BaseServiceImpl;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品三级分类 服务实现类
 * </p>
 *
 * @author 咸蛋超人
 * @since 2023-12-27
 */
@Service
public class CategoryServiceImpl extends BaseServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Override
    public PageData<Category> page(Map<String, Object> params) {
        IPage<Category> page = baseDao.selectPage(
                getPage(params, "", true),
                getWrapper(params)
        );
        return getPageData(page, Category.class);
    }

    @Override
    public Category get(Long id) {
        return baseDao.selectById(id);
    }

    @Override
    public List<Category> getList(Category dto) {
        QueryWrapper<Category> wrapper = new QueryWrapper<>();
        return baseDao.selectList(wrapper);
    }

    @Override
    public String save(Category dto) {
        insert(dto);
        return dto.getCatId().toString();
    }

    @Override
    public void saveList(List<Category> list) {
        insertBatch(list);
    }

    @Override
    public void update(Category dto) {
        updateById(dto);
    }

    @Override
    public void updateList(List<Category> list) {
        updateBatchById(list);
    }

    @Override
    public void remove(Long id) {
        deleteById(id);
    }

    @Override
    public void removeList(List<Long> idList) {
        deleteBatchIds(idList);
    }

    @Override
    public List<Category> listWithTree() {
        List<Category> categoryList = baseDao.selectList(null);
        return categoryList.stream().
                filter(category -> category.getParentCid() == 0)
                .peek((menu) -> menu.setChildren(getChildren(menu, categoryList)))
                .sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
                .collect(Collectors.toList());
    }

    @Override
    public void removeMenuList(List<Long> idList) {
        //TODO 1检查菜单是否被引用
        baseDao.deleteBatchIds(idList);
    }

    private List<Category> getChildren(Category root, List<Category> all) {
        return all.stream()
                .filter(category -> Objects.equals(category.getParentCid(), root.getCatId()))
                .peek(category -> category.setChildren(getChildren(category, all)))
                .sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
                .collect(Collectors.toList());
    }

    @SneakyThrows
    private QueryWrapper<Category> getWrapper(Map<String, Object> params) {
        QueryWrapper<Category> wrapper = new QueryWrapper<>();
        for (String key : params.keySet()) {
            Field[] fields = Category.class.getDeclaredFields();
            boolean b = Arrays.stream(fields).anyMatch(field -> field.getName().equals(key));
            if (b) {
                Field field = Category.class.getDeclaredField(key);
                Class<?> type = field.getType();
                String fieldUnderline = StringUtils.capitalize(key);
                Object value = params.get(key);
                wrapper.eq(fieldUnderline, type.cast(value));
            }
        }
        return wrapper;
    }
}
